<?php
/**
 * 模块基类
 * 
 * Created		: 2011-07-06
 * Modified		: 2011-07-20 
 * @link		: http://www.itblog.org
 * @copyright	: (C) 2011 ITBlog Inc.
 * @version		: 1.0.0
 * @author		: Joseph Chen (jsph.chen@gmail.com)
 */
class Model
{
	// 表名前缀
	protected $tblPre	= null;
	protected $tbl		= 'model';// 不含前缀的表名
	protected $_tbl		= '';// 组合表前缀后的完整表名
	protected $priKey	= 'id';
	protected $fields	= array();
	
	protected $errors	= null;
	
	protected $pageSize = 20;
	
	public $pagePanel	= '';
	
	
	public function __construct($tbl='', $tblPre='')
	{
		if ($tblPre) {
			$this->tblPre = $tblPre;
		} elseif (is_null($this->tblPre)) {
			$this->tblPre = $GLOBALS['tblPre'];
		}
		if ($tbl) {
			$this->tbl = $tbl;
		}
		$this->_tbl = $this->tblPre.$this->tbl;
		
		// 载入字段配置
		$this->fields = C('fields/'.$this->tbl);
		
		return $this;
	}
	
	/**
	 * 向表中插入一条数据
	 * @param array $data
	 */
	public function add2Table($data)
	{
		$ret = $this->validateFields($data);
		if (!$ret) {
			return false;
		}
		$ret = Db::insert($this->_tbl, $data);
		if ($ret) {
			$this->errors(null);
			return true;
		} else {
			$errors = Db::errors();
			$this->errors(
				array(
					'code'	=> $errors[1],
					'info'	=> $errors[2]
				)
			);
			return false;
		}
	}
	
	/**
	 * 根据条件更新表中的数据
	 * @param array $data
	 * @param string $where
	 * @param array $params
	 */
	public function updateTable($data, $where='', $params)
	{
		
		$ret = $this->validateFields($data);
		if (!$ret) {
			return false;
		}
		$ret = Db::update($this->_tbl, $data, $where, $params);
		if ($ret) {
			$this->errors(null);// 清空错误信息
			return true;
		} else {
			$errors = Db::errors();
			$this->errors(
				array(
					'code'	=> $errors[1],
					'info'	=> $errors[2]
				)
			);
			return false;
		}
	}
	
	public function validateFields($data)
	{
		if ($this->fields) {
			foreach ($this->fields as $field_name => $cfg)
			{
				if (!isset($data[$field_name])) {
					$data[$field_name] = $cfg['df_val'];
				} else{
					$val = $data[$field_name];
					if ($cfg['type']=='int' && !(is_int($val) || ctype_digit($val)) ) {
						$this->errors(
							array(
								'code'	=> $GLOBALS['CDataTypeIsNotInt'],
								'msg'	=> sprintf($GLOBALS['MDataTypeIsNotInt'], $field_name),
							)
						);
						$ret = false;
						break;
					} elseif ($cfg['type']=='float' && !is_numeric($val)) {
						$this->errors(
							array(
								'code'	=> $GLOBALS['CDataTypeIsNotFloat'],
								'msg'	=> sprintf($GLOBALS['MDataTypeIsNotFloat'], $field_name),
							)
						);
						$ret = false;
						break;
					} elseif ($cfg['type']=='string') {
						$len = mb_strlen($val);
						if ((isset($cfg['min_len']) && $len < $cfg['min_len'])
								 || (isset($cfg['max_len']) && $len > $cfg['max_len']) 
						) {
							$this->errors(
								array(
									'code'	=> $GLOBALS['CStringLenError'],
									'msg'	=> sprintf(
												$GLOBALS['MStringLenError'], 
												$field_name,
												$cfg['min_len'], $cfg['max_len']
									)
								)
							);
							$ret = false;
							break;
						}
					}
				}
			}
		}
		if ($ret) {
			$this->errors(null);
			return true;
		} else {
			$this->errors(
				array(
					'code'	=> $GLOBALS['CMysqlFieldsDataInvalid'],
					'info'	=> $GLOBALS['MMysqlFieldsDataInvalid']
				)
			);
			return false;
		}
	}
	
	/**
	 * 读取一条记录
	 * Enter description here ...
	 * @param mix $val
	 * @param string $field
	 */
	public function read($val, $field='')
	{
		if ($field) {
			return Db::read($this->_tbl, $val, $field);
		} else {
			return Db::read($this->_tbl, $val, $this->priKey);
		}
	}
	
	/**
	 * 删除记录
	 * @param string $where
	 */
	public function delete($where='', $params=null)
	{
		$ret = Db::delete($this->_tbl, $where, $params);
		if ($ret) {
			$this->errors(null);
			return true;
		} else {
			$errors = Db::errors();
			$this->errors(
				array(
					'code'	=> $errors[1],
					'info'	=> $errors[2]
				)
			);
			return false;
		}
	}
	
	/**
	 * 根据条件得到表的记录数
	 * @param string|array $where
	 */
	public function getCounts($where)
	{
		if (is_string($where)) {
			return Db::getCounts($this->_tbl, $where);
		} else {
			return Db::getCounts($this->_tbl, join(' and ', $where));
		}
	}
	
	/**
	 * 获取列表数据
	 * @param array $args
	 */
	public function getList($args=array())
    {
        extract($args);
        
        !isset($page_size) && $page_size = $this->pageSize;
        
    	if (empty($where))
    	{
			$_whr = array();
		} elseif (is_string($where)) {
			$_whr = array($where);
		} elseif (is_array($where)) {
			$_whr = $where;
		} else {
			$_whr = array();
		}
		
		(!isset($params) || !is_array($params)) && $params = array();
		if (!empty($cid))
		{
			$_whr[] = 'cid=:cid';
			$params['cid'] = $cid;
		}
		if (isset($status) && $status != 'all') {
			$_whr[] = 'status=:status';
			$params['status'] = $status;
		}

        //关键字查询
        if (!empty($_whr))
        {
	        $where = join(' and ', $_whr);
			$where = ' where '.$where;
        } else {
        	$where = '';
        	$params = null;
        }
        $rows = Db::getCounts($this->_tbl, $where, $params);
        if (!$rows && !is_null(Db::$errors)) {
        	$this->errors(
				array(
					'code'	=> Db::$errors[1],
					'info'	=> Db::$errors[2]
				)
			);
			return false;
        }
		if (!empty($has_pages))
		{
			Page::init($page_size, $rows);
			Page::set_from_to($page_size);
			$page_start = Page::$from;
		} else {
			$has_pages = false;
			$page_start = 0;
		}
		empty($fields) && $fields = '*';
		if (empty($order))
		{
			$order = ' order by '.$this->priKey.' desc';
		} else {
			$order = ' order by '.$order;
		}
		$sql = 'select '.$fields.' from '.$this->_tbl.' '
				.$where.$order." limit $page_start, $page_size";
        $list = Db::fetches($sql, $params);
		//如果列表有分页,则进行分页操作
        if ($has_pages == 1)
		{
			$this->page_panel = Page::generate($_POST);
		}
        return $list;
	}
	
	/**
	 * 返回/设置错误信息
	 * @param $errors false-返回错误信息,其它参数设置错误信息
	 */
	public function errors($errors=false)
	{
		if ($errors === false) {
			return $this->errors;
		} else {
			$this->errors = $errors;
			return $this->errors;
		}
	}
}












